﻿/*
 * ArrayImpl.h
 *
 *  Created on: 2011/05/28
 *      Author: naoki
 */

#ifndef INCLUDED_NTENGINE_ARRAYIMPL_H
#define INCLUDED_NTENGINE_ARRAYIMPL_H

#include "NTEngine/NTEngine.h"
#include "NTEngine/Base/Array.h"

namespace NTEngine {

template< class T > inline Array<T>::Array()
: m_Elements( 0 )
, m_Size( 0 ) {
}

template< class T > inline Array< T >::Array( int size )
: m_Elements( 0 )
, m_Size( size ) {
	if ( m_Size > 0 ) {
		m_Elements = static_cast< T* >( OPERATOR_NEW( sizeof( T ) * m_Size ) );
		for ( int i = 0; i < m_Size; ++i ) {
			new ( &m_Elements[ i ] ) T;
		}
	}
}

template< class T > inline Array< T >::Array( int size, const T& a )
: m_Elements( 0 )
, m_Size( size ) {
	if ( m_Size > 0 ) {
		m_Elements = static_cast< T* >( OPERATOR_NEW( sizeof( T ) * m_Size ) );
		for ( int i = 0; i < m_Size; ++i ) {
			new ( &m_Elements[ i ] ) T( a );
		}
	}
}


template< class T > inline Array< T >::~Array() {
	clear();
}

template< class T > inline const T& Array< T >::operator[]( int i ) const {
	HARD_ASSERT( ( i < m_Size ) && "<Array::operator[]> : 配列オーバーフロー");
	return m_Elements[ i ];
}

template< class T > inline T& Array< T >::operator[]( int i ) {
	HARD_ASSERT( ( i < m_Size ) && "<Array::operator[]> : 配列オーバーフロー");
	return m_Elements[ i ];
}

template<class T> inline void Array<T>::setSize( int size ) {
	// 空か縮小するんなら処理する
	if ( !m_Elements ) {
		m_Elements = static_cast< T* >( OPERATOR_NEW( sizeof( T ) * size ) );
		for ( int i = 0; i < size; ++i ) {
			new ( &m_Elements[ i ] ) T;
		}
	}
	else {
		HARD_ASSERT( ( size <= m_Size ) && "<Array::SetSize> : 拡張はサポートしてない" );
		for ( int i = size; i < m_Size; ++i ) {
			// はみ出した部分をデストラクト
			m_Elements[ i ].~T();
		}
	}
	m_Size = size;
}

template<class T> inline int Array<T>::size() const {
	return m_Size;
}

template<class T> inline void Array<T>::clear() {
	for ( int i = 0; i < m_Size; ++i ) {
		m_Elements[ i ].~T();
	}
	OPERATOR_DELETE( m_Elements );
	m_Size = 0;
}

} // namespace NTEngine

#endif // INCLUDED_NTENGINE_ARRAYIMPL_H
